using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.IO;
using System.Text;
using ZoneFiveSoftware.Common.Data;
using ZoneFiveSoftware.Common.Data.Fitness;
using ZoneFiveSoftware.Common.Visuals;
using FilteredStatistics.Common;
using FilteredStatistics.Common.Controller;
using FilteredStatistics.Controller;
using FilteredStatistics.View;

namespace FilteredStatistics.Data
{
    class RecordedLapsFilterCriteria : FilterCriteriaFacade, ISplitsCriteria
    {
        public RecordedLapsFilterCriteria(IActivity activity)
        {
            m_ActivityCallbackHelper = new ActivityDataChangedHelper(activity);
            m_ActivityCallbackHelper.PropertyChanged += new PropertyChangedEventHandler(OnActivityDataChanged);

            Init(activity);
        }

#region FilterCriteriaFacade Members

        public override Guid ReferenceId
        {
            get { return GUIDs.SplitsCriteriaGuid; }
        }

        public override IActivity Activity
        {
            set
            {
                if (m_Activity != value)
                {
                    m_Activity = value;
                    m_ActivityCallbackHelper.Activity = m_Activity;

                    // Refresh activity on "all active" and "all rest" named zones
                    foreach (INamedZone namedZone in m_SplitsNamedZones)
                    {
                        AllActiveOrRestLapsNamedZone activeRestZone = namedZone as AllActiveOrRestLapsNamedZone;

                        if (activeRestZone != null)
                        {
                            activeRestZone.Activity = m_Activity;
                        }
                    }

                    CreateSplitsNamedZonesList();
                }
            }
        }

        public override string DisplayName
        {
            get { return PluginView.GetLocalizedString("RecordedLapsText"); }
        }

        public override bool IsTemplateOnly
        {
            get { return false; }
        }

        public override bool IsMainViewOnly
        {
            get { return false; }
        }

        public override List<object> NamedZones
        {
            get { return m_SplitsNamedZones; }
        }

        public override bool IsSerializable
        {
            get { return false; }
        }

        public override UInt16 DataVersion
        {
            get { return Constants.CurrentVersion.VersionNumber; }
        }

        public override object DeserializeCriteria(Stream stream, UInt16 dataVersion)
        {
            Debug.Assert(false);

            return null;
        }

        public override void SerializeCriteria(Stream stream)
        {
            Debug.Assert(false);
        }

        public override object TemplateCompatibleCriteria
        {
            get
            {
                return new TemplateRecordedLapsFilterCriteria(m_Activity);
            }
        }

#endregion

#region ISplitsCriteria Members

        public SplitsCriteriaType SplitsType
        {
            get { return SplitsCriteriaType.RecordedLaps; }
        }

#endregion

#region IPluginSerializable members

        public override void Serialize(Stream stream)
        {
            // We should never end up with this in a template
            Debug.Assert(false);
        }

#endregion

        public override int GetHashCode()
        {
            return base.GetHashCode();
        }

        public override bool Equals(object obj)
        {
            RecordedLapsFilterCriteria criteria = obj as RecordedLapsFilterCriteria;
            SplitsPlaceholderFilterCriteria criteriaPlaceholder = obj as SplitsPlaceholderFilterCriteria;

            if (criteria != null || criteriaPlaceholder != null)
            {
                return true;
            }

            return base.Equals(obj);
        }

        public void Init(IActivity activity)
        {
            Activity = activity;
        }

        private void OnActivityDataChanged(object sender, PropertyChangedEventArgs e)
        {
            if (e.PropertyName == "Activity.Laps")
            {
                CreateSplitsNamedZonesList();
                TriggerNamedZonesListChanged();
            }
        }

        private void CreateSplitsNamedZonesList()
        {
            if (m_Activity != null)
            {
                if (m_SplitsNamedZones.Count == 0)
                {
                    m_SplitsNamedZones.Add(new AllActiveOrRestLapsNamedZone(m_Activity, false));
                    m_SplitsNamedZones.Add(new AllActiveOrRestLapsNamedZone(m_Activity, true));
                }

                // Remove all but the first 2 (all active & all rest)
                m_SplitsNamedZones.RemoveRange(2, m_SplitsNamedZones.Count - 2);

                // Create a named zone for each lap
                for (int lapIndex = 0; lapIndex < m_Activity.Laps.Count; ++lapIndex)
                {
                    m_SplitsNamedZones.Add(new RecordedLapNamedZone(m_Activity, lapIndex));
                }
            }

            TriggerNamedZonesListChanged();
        }

        private IActivity m_Activity = null;
        private ActivityDataChangedHelper m_ActivityCallbackHelper = null;
        private List<object> m_SplitsNamedZones = new List<object>();
    }
}
